package com.qk.management.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qk.common.PageResult;
import com.qk.common.constant.BusinessStatusConstants;
import com.qk.common.constant.ClueStatusConstants;
import com.qk.common.constant.ClueTrackRecordStatus;
import com.qk.common.enums.ParamEnum;
import com.qk.common.exception.CommonException;
import com.qk.common.util.CurrentUserContextHolders;
import com.qk.domain.clue.ClueDO;
import com.qk.dto.clue.*;
import com.qk.entity.Business;
import com.qk.entity.Clue;
import com.qk.entity.ClueTrackRecord;
import com.qk.management.mapper.*;
import com.qk.management.service.ClueService;
import com.qk.vo.clue.CluePoolVO;
import com.qk.vo.clue.clueVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *
 *
 * @author blusr
 * @version 1.0
 * @date 2025/10/13 17:38
 */
@Service
@SuppressWarnings("all")
public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements ClueService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ClueMapper clueMapper;
    @Autowired
    private ClueTrackRecordMapper clueTrackRecordMapper;
    @Autowired
    private BusinessMapper businessMapper;
    @Autowired
    private ActivityMapper activityMapper;

    @Override
    public PageResult<CluePoolVO> cluePoolList(CluePoolPageDTO dto) {
        Page<Clue> page = page(new Page<>(dto.getPage(), dto.getPageSize())
                , Wrappers.lambdaQuery(Clue.class)
                        .eq(ObjectUtil.isNotEmpty(dto.getClueId()), Clue::getId, dto.getClueId())
                        .eq(ObjectUtil.isNotEmpty(dto.getChannel()), Clue::getChannel, dto.getChannel())
                        .like(ObjectUtil.isNotEmpty(dto.getPhone()) && !ObjectUtil.equals(dto.getPhone(), ""), Clue::getPhone, dto.getPhone())
                        .eq(Clue::getStatus, ClueStatusConstants.CLUE_STATUS_PENDING)
                        .orderByDesc(Clue::getUpdateTime));
        List<CluePoolVO> collect = page.getRecords().stream().map(clue -> {
            CluePoolVO cluePoolVO = BeanUtil.copyProperties(clue, CluePoolVO.class);
            cluePoolVO.setActivityName(ObjectUtil.isNotEmpty(activityMapper.selectById(cluePoolVO.getActivityId())) ? activityMapper.selectById(cluePoolVO.getActivityId()).getName() : "");
            return cluePoolVO;
        }).collect(Collectors.toList());
        return PageResult.<CluePoolVO>builder()
                .total(page.getTotal())
                .rows(collect)
                .build();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void toFalseClue(Integer id, ClueFalseDTO dto) {
        Clue clue = clueMapper.selectById(id);
        if(Objects.isNull(clue)){
            CommonException.throwCommonException(ParamEnum.PARAM_ERROR);
        }
        clue.setStatus(ClueStatusConstants.CLUE_STATUS_PENDING);
        clue.setUpdateTime(LocalDateTime.now());
        clueMapper.updateById(clue);

        ClueTrackRecord trackRecord = new ClueTrackRecord();
        trackRecord.setClueId(id);
        trackRecord.setUserId(clue.getUserId());
        trackRecord.setSubject(clue.getSubject());
        trackRecord.setLevel(clue.getLevel());
        trackRecord.setRecord(dto.getRemark());
        trackRecord.setType(ClueTrackRecordStatus.FAKE);
        trackRecord.setFalseReason(dto.getReason());
        trackRecord.setCreateTime(LocalDateTime.now());
        clueTrackRecordMapper.insert(trackRecord);
    }

    @Override
    public void addClue(ClueDTO dto) {
        if(Objects.isNull(dto.getPhone()) || Objects.equals(dto.getPhone(), "") || Objects.isNull(dto.getChannel())){
            CommonException.throwCommonException(ParamEnum.PARAM_ERROR);
        }
        Clue clue = BeanUtil.copyProperties(dto, Clue.class);
        clue.setStatus(ClueStatusConstants.CLUE_STATUS_UNASSIGNED);
        clue.setCreateTime(LocalDateTime.now());
        clue.setUpdateTime(LocalDateTime.now());
        save(clue);
    }

//    @Override
//    public PageResult<ClueDO> clueList(CluePageDTO dto) {
//        PageHelper.startPage(dto.getPage(), dto.getPageSize());
//        List<ClueDO> clueDOList = clueMapper.selectByPage(dto);
//        Page<ClueDO> page = (Page<ClueDO>) clueDOList;
//        return PageResult.<ClueDO>builder()
//                .total(page.getTotal())
//                .rows(page.getResult())
//                .build();
//    }

    @Override
    public PageResult<ClueDO> clueListMP(CluePageDTO dto) {
        Page<Clue> page = new Page<>(dto.getPage(), dto.getPageSize());
        Page<ClueDO> clueDOList = clueMapper.selectByPageMP(page,dto);
        return PageResult.<ClueDO>builder()
                .total(clueDOList.getTotal())
                .rows(clueDOList.getRecords())
                .build();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public clueVO getClueInfoById(Integer id) {
        Clue clue = clueMapper.selectById(id);
        clueVO vo = BeanUtil.copyProperties(clue, clueVO.class);
        List<clueVO.ClueTrackRecordVO> trackRecords = new ArrayList<>();
        clueTrackRecordMapper.selectList(Wrappers.lambdaQuery(ClueTrackRecord.class)
                .in(ClueTrackRecord::getClueId, id)
                .orderByDesc(ClueTrackRecord::getCreateTime))
                .forEach(record -> {
            clueVO.ClueTrackRecordVO clueTrackRecordVO = BeanUtil.copyProperties(record, clueVO.ClueTrackRecordVO.class);
            clueTrackRecordVO.setAssignName(userMapper.selectById(clue.getUserId()).getName());
            trackRecords.add(clueTrackRecordVO);
        });
        vo.setTrackRecords(trackRecords);
        return vo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateClueInfoById(UpdateClueInfoDTO dto) {
        if(dto.getNextTime().isBefore(LocalDateTime.now())){
            CommonException.throwCommonException(ParamEnum.NEXT_TIME_ERROR);
        }
        Clue clue = BeanUtil.copyProperties(dto, Clue.class);
        clue.setUpdateTime(LocalDateTime.now());
        if (Objects.equals(clue.getStatus(), ClueStatusConstants.CLUE_STATUS_FOLLOWED)) {
            clue.setStatus(ClueStatusConstants.CLUE_STATUS_FOLLOWING);
        }
        clue.setUserId(CurrentUserContextHolders.getUserId());
        updateById(clue);
        ClueTrackRecord clueTrackRecord = BeanUtil.copyProperties(dto, ClueTrackRecord.class);
        clueTrackRecord.setId(null);
        clueTrackRecord.setType(ClueTrackRecordStatus.NORMAL);
        clueTrackRecord.setClueId(dto.getId());
        clueTrackRecord.setCreateTime(LocalDateTime.now());
        clueTrackRecord.setUserId(CurrentUserContextHolders.getUserId());
        clueTrackRecordMapper.insert(clueTrackRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void toBusiness(Integer clueId) {
        Clue clue = clueMapper.selectById(clueId);
        clue.setStatus(ClueStatusConstants.CLUE_STATUS_TO_BUSINESS);
        clue.setUpdateTime(LocalDateTime.now());
        clueMapper.updateById(clue);

        Business business = BeanUtil.copyProperties(clue, Business.class);
        business.setId(null);
        business.setUserId(null);
        business.setClueId(clueId);
        business.setNextTime(null);
        business.setCreateTime(LocalDateTime.now());
        business.setUpdateTime(LocalDateTime.now());
        business.setStatus(BusinessStatusConstants.BUSINESS_STATUS_UNASSIGNED);
        businessMapper.insert(business);
    }
}
